<template>
  <el-card style="height: 80px">
    <el-form :inline="true" class="form">
      <el-form-item label="角色名称:">
        <el-input
          placeholder="请输入搜索角色名"
          v-model.trim="keyword"></el-input>
      </el-form-item>
      <el-form-item>
        <el-button
          type="primary"
          :icon="Search"
          :disabled="keyword ? false : true"
          @click="handleSearch"
          >搜索</el-button
        >
        <el-button :icon="Refresh" @click="reset">重置</el-button>
      </el-form-item>
    </el-form>
  </el-card>
  <el-card style="margin-top: 10px">
    <el-button color="#626aef" :icon="Plus" @click="addRole"
      >新增角色</el-button
    >
    <el-table style="margin: 10px 0" border :data="roleList">
      <el-table-column label="#" type="index"> </el-table-column>
      <el-table-column
        label="id"
        property="_id"
        header-align="center"
        show-overflow-tooltip>
      </el-table-column>
      <el-table-column
        label="角色名称"
        min-width="60"
        align="center"
        property="name"
        header-align="center"></el-table-column>
      <el-table-column
        label="创建时间"
        align="center"
        property="createdAt"
        header-align="center"
        show-overflow-tooltip></el-table-column>
      <el-table-column
        label="更新时间"
        align="center"
        property="updatedAt"
        show-overflow-tooltip
        header-align="center"></el-table-column>
      <el-table-column label="操作" width="380" header-align="center">
        <template #default="{ row }">
          <el-row justify="center">
            <el-button
              type="success"
              small
              :icon="Plus"
              @click="assignPermission(row)"
              >分配权限</el-button
            >
            <el-button
              type="primary"
              small
              :icon="Edit"
              @click="updateRole(row)"
              >编辑</el-button
            >
            <el-popconfirm
              :title="`你确定要删除&quot;${row.roleName}&quot;吗？`"
              width="220px"
              @confirm="removeRole(row._id)">
              <template #reference>
                <el-button type="danger" small :icon="Delete" :loading="loading"
                  >删除</el-button
                >
              </template>
            </el-popconfirm>
          </el-row>
        </template>
      </el-table-column>
    </el-table>
    <el-pagination
      v-model:current-page="currentPage"
      v-model:page-size="pageSize"
      :page-sizes="[5, 10, 15, 20]"
      :background="true"
      layout="prev, pager, next, jumper,->,sizes,total"
      :total="totalItem"
      @current-change="handleCurrentChange"
      @size-change="sizeChange" />
  </el-card>
  <!-- 添加职位与更新已有职位的结构:对话框 -->
  <el-dialog
    v-model="dialogVisite"
    :title="roleParams._id ? '更新职位' : '添加职位'">
    <el-form :model="roleParams" :rules="rules" ref="ruleFormRef">
      <el-form-item label="角色的名称" prop="roleName">
        <el-input
          placeholder="请你输入角色的名称"
          v-model="roleParams.name"></el-input>
      </el-form-item>
      <el-form-item label="角色的描述" prop="roleDesc">
        <el-input
          placeholder="角色的描述"
          v-model="roleParams.roleDesc"></el-input>
      </el-form-item>
    </el-form>
    <template #footer>
      <el-button
        type="primary"
        size="default"
        @click="save(ruleFormRef)"
        :loading="loading"
        >提交</el-button
      >
      <el-button @click="dialogVisite = false">取消</el-button>
    </template>
  </el-dialog>
  <!-- 抽屉组件:分配职位的菜单权限与按钮的权限 -->
  <el-drawer v-model="drawer">
    <template #header>
      <h4>
        分配菜单与按钮的权限;角色名称：<strong>{{ roleParams.name }}</strong>
      </h4>
    </template>
    <template #default>
      <!-- 树形控件 -->
      <el-input v-model="filterText" placeholder="过滤关键字" />
      <el-tree
        ref="treeRef"
        class="filter-tree"
        show-checkbox
        node-key="_id"
        highlight-current
        accordion
        :data="treeData"
        :props="defaultProps"
        :default-checked-keys="ids"
        :default-expanded-keys="ids"
        :filter-node-method="filterNode" />
    </template>
    <template #footer>
      <div style="flex: auto">
        <el-button type="primary" @click="savePermission" :loading="loading"
          >提交</el-button
        >
        <el-button @click="drawer = false">取消</el-button>
      </div>
    </template>
  </el-drawer>
</template>

<script setup lang="ts" name="Role">
  import { ref, reactive, toRefs, onMounted, watch } from "vue";
  import { Search, Refresh, Plus, Edit, Delete } from "@element-plus/icons-vue";
  import { storeToRefs } from "pinia";
  import { ElMessage } from "element-plus";
  import type { FormInstance, FormRules, ElTree } from "element-plus";

  import type { IRoleBase } from "@/apis/acl/role/type";
  import useLayoutSettingStore from "@/store/modules/setting";
  import useRoleStore from "@/store/modules/role";
  import type { IPermission } from "@/apis/acl/menu/type";
  import { listToTree } from "@/utils/tools";

  //#region 数据状态

  const layoutStore = useLayoutSettingStore();
  const roleStore = useRoleStore();
  const {
    roleList,
    currentPage,
    pageSize,
    totalItem,
    keyword,
    loading,
    permissions,
    // permissionTree,
  } = storeToRefs(roleStore);
  const state = reactive<{
    dialogVisite: boolean;
    roleParams: IRoleBase;
    drawer: boolean;
    treeData: IPermission[];
    ids: string[];
    filterText: string;
  }>({
    dialogVisite: false,
    roleParams: { name: "" },
    drawer: false,
    treeData: [],
    ids: [],
    filterText: "",
  });

  const { dialogVisite, roleParams, drawer, ids, filterText, treeData } =
    toRefs(state);

  const defaultProps = {
    children: "children",
    label: "name",
  };

  const getHasRole = async (pager = 1) => {
    await roleStore.getRoleList(pager);
  };

  onMounted(() => {
    getHasRole();
  });

  //#endregion

  //#region 表单校验
  const ruleFormRef = ref<FormInstance>();

  const rules = reactive<FormRules<IRoleBase>>({
    name: [
      {
        required: true,
        message: "请你输入有效职位名称",
        trigger: "blur",
      },
      {
        min: 2,
        max: 10,
        message: "职位名称长度在2到10个字符",
        trigger: "blur",
      },
    ],
  });

  //#region 分页逻辑
  const sizeChange = (val: number) => {
    pageSize.value = val;
    currentPage.value = 1;
    getHasRole();
  };

  const handleCurrentChange = (val: number) => {
    currentPage.value = val;
    getHasRole(currentPage.value);
  };

  //#endregion

  //#endregion

  //#region table按钮操作逻辑

  //搜索按钮的回调
  const handleSearch = () => {
    getHasRole();
    keyword.value = "";
  };

  /** 执行重置刷新按钮逻辑 */
  const reset = () => {
    layoutStore.refresh = !layoutStore.refresh;
  };

  /**
   *添加职位按钮的回调
   */
  const addRole = () => {
    dialogVisite.value = true;
    roleParams.value = { name: "" };
    ruleFormRef.value?.resetFields();
  };

  const updateRole = async (row: any) => {
    dialogVisite.value = true;
    Object.assign(roleParams.value, row);
  };

  const removeRole = async (id: string) => {
    await roleStore.deleteRole(id);
  };

  // 权限分配
  const assignPermission = async (row: IRoleBase) => {
    drawer.value = true;
    Object.assign(roleParams.value, row);
    // 树结构初始化
    treeData.value = [];
    // 1. 获取权限树
    // 1.1 判断是否已经请求过权限列表,如没有数据，请求，

    if (permissions.value.length === 0) {
      await roleStore.getPermissions();
    }
    // 1.2 如果有数据，直接使用，减少请求次数，优化
    // 2. 获取当前角色的权限id
    ids.value = [...row.permissionIds!];

    const res = permissions.value.map(item => {
      return {
        ...item,
        select: ids.value.includes(item._id!) ? true : false,
      };
    });
    // 3. 回显
    treeData.value = listToTree(res);
  };

  //#endregion

  //#region 表单操作
  const save = async (formEl: FormInstance | undefined) => {
    if (!formEl) return;
    const valid = await formEl.validate();
    if (!valid) {
      ElMessage.error("请按照要求填写表单！");
      return;
    }
    await saveOrUpdate();
  };

  const saveOrUpdate = async () => {
    await roleStore.addOrUpdateRole(roleParams.value);
    dialogVisite.value = false;
  };

  //#endregion

  //#region 树形结构操作
  const treeRef = ref<InstanceType<typeof ElTree>>();

  watch(filterText, val => {
    treeRef.value!.filter(val);
  });

  const filterNode = (value: string, data: any) => {
    if (!value) return true;
    // console.log(data, value);
    return data.label.includes(value);
  };

  const savePermission = async () => {
    const selectedKeys = treeRef.value?.getCheckedKeys()!;
    // const halfCheckedKeys = treeRef.value?.getHalfCheckedKeys()!;

    roleParams.value.permissionIds = [...(selectedKeys as string[])];
    await saveOrUpdate();
    drawer.value = false;
  };

  //#endregion
</script>

<style scoped lang="scss">
  .form {
    /* 弹性布局 水平两边 垂直居中;*/
    display: flex;
    justify-content: space-between;
    align-items: center;
  }
</style>
